# -*- coding: utf-8 -*-

#   Copyright (C) 2011  P.L. Lucas, P.L. del Castillo
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

from math import *
from fx import *
from image_ops import *


#Listado de transiciones. En cada subclase de FX hay que indicar correctamente el self.class_base en __init__
def transitions_list():
	list={
			'None': None,
			'Fade': TransitionFade,
			'ZoomIn': TransitionZoomIn,
			'ZoomOut': TransitionZoomOut,
			'Squares flying 1': TransitionSquaresFlying1,
			'Squares flying 2': TransitionSquaresFlying2,
			'Squares flying 3': TransitionSquaresFlying3,
			'Squares flying 4': TransitionSquaresFlying4,
			'Squares flying 5': TransitionSquaresFlying5,
			'Push left': TransitionPushLeft,
			'Push up': TransitionPushUp,
			'Circle close': TransitionCircleClose,
			'Circle open': TransitionCircleOpen,
			'Figure rectangle': TransitionFigureBase,
			'Figure heart': TransitionFigureHeart,
			'Figure star 5': TransitionFigureStar5,
			'Figure star multiple': TransitionFigureStarMultiple
		}
	return list

class TransitionFade(FX):
	def __init__(self, videoProperties, duration):
		FX.__init__(self, videoProperties, duration)
		self.xml_tag_name='transition'
		self.class_base=TransitionFade
		self.icon_path=install_path+'/icons/fadeout.svg'
	
	def get_name(self):
		return self.class_name()
	
	def class_name(self):
		for k,v in transitions_list().iteritems():
			if self.class_base==v:
				return k 
		return None
	
	def xml(self):
		return self.xml_generate(['duration'])
	
	def icon(self, pixbuf):
		pix=self.icon_add_icon( pixbuf, self.icon_path, 0, 64-64/4)
		pixmap=gtk.gdk.Pixmap(None, pix.get_width(), pix.get_height(), 24)
		ct=pixmap.cairo_create()
		ct.set_source_pixbuf(pix,0,0)
		ct.paint()
		ct.set_source_rgb(1,1,1)
		ct.set_font_size(64/4-4)
		ct.move_to(64/4*2, pix.get_height()-2)
		ct.show_text(str(self.duration)+' s')
		#ct.fill()
		#ct.paint()
		pix=gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, pix.get_width(), pix.get_height())
		pix=pix.get_from_drawable(pixmap, pixmap.get_colormap(), 0,0,0,0, pix.get_width(), pix.get_height())
		return pix

	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint()
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint_with_alpha(float(self.duration-t)/float(self.duration))
		if float(self.duration-t)/float(self.duration)>1.0:
			print "Satura"
			print "duration="+str(self.duration)
			print "t="+str(t)
		if float(self.duration-t)/float(self.duration)<0.0:
			print "In Satura"
		return imageSurface_get_pixbuf(im)

class TransitionZoomOut(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		self.class_base=TransitionZoomOut
		self.icon_path=install_path+'/icons/zoomout.svg'
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint()
		factor=1.0-float(t)/float(self.duration)
		ct.translate(self.videoProperties.width/2, self.videoProperties.height/2)
		ct.scale(factor, factor)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),-self.videoProperties.width/2, -self.videoProperties.height/2)
		ct.paint()
		return imageSurface_get_pixbuf(im)


class TransitionZoomIn(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		self.class_base=TransitionZoomIn
		self.icon_path=install_path+'/icons/zoomin.svg'
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint()
		factor=float(t)/float(self.duration)
		if factor<0.01:
			factor=0.01
		elif factor>1.0:
			factor=1.0
		#print 'factor={0}'.format(factor)
		ct.translate(self.videoProperties.width/2, self.videoProperties.height/2)
		ct.scale(factor, factor)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),-self.videoProperties.width/2, -self.videoProperties.height/2)
		ct.paint()
		return imageSurface_get_pixbuf(im)

class TransitionSquaresFlying1(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		self.class_base=TransitionSquaresFlying1
		self.icon_path=install_path+'/icons/squaresflying1.svg'
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		factor=float(t)/float(self.duration)
		if factor<0.0:
			factor=0.0
		elif factor>1.0:
			factor=1.0
		for n in range(0,2):
			if n==0:
				ct.save()
			if (factor<0.5 and n==0) or (factor>=0.5 and n==1):
				x=float(self.videoProperties.width/2.0)*(1.0-sin(factor*pi))
				ct.translate(x, self.videoProperties.height/2)
				scale=factor*0.5+0.5
				ct.scale(scale, scale)
				ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),-self.videoProperties.width/2, -self.videoProperties.height/2)
				ct.paint()
			else:
				x=float(self.videoProperties.width/2.0)*(1.0-sin(factor*pi+pi))
				ct.translate(x, self.videoProperties.height/2)
				scale=1.0-factor*0.5
				ct.scale(scale, scale)
				ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),-self.videoProperties.width/2, -self.videoProperties.height/2)
				ct.paint()
			if n==0:
				ct.restore()
		return imageSurface_get_pixbuf(im)




class TransitionSquaresFlyingBase(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		#self.class_base=TransitionSquaresFlying1
		#self.icon_path=install_path+'/icons/zoomin.svg'
	
	def coord_pixbuf1(self, t):
		x=self.videoProperties.width/2
		y=self.videoProperties.height/2
		z=1.0
		scale=1.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		return self.coord_pixbuf1(t)
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		factor=float(t)/float(self.duration)
		if factor<0.0:
			factor=0.0
		elif factor>1.0:
			factor=1.0
		x1, y1, z1, scale1, angle1, alpha1=self.coord_pixbuf1(factor)
		x2, y2, z2, scale2, angle2, alpha2=self.coord_pixbuf2(factor)
		for n in range(0,2):
			if n==0:
				ct.save()
			if (z1>z2 and n==0) or (z1<=z2 and n==1):
				if scale2>0.01: #If scale is low, cairo can not scale the picture
					ct.translate(x2, y2)
					ct.scale(scale2, scale2)
					ct.rotate(angle2)
					ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),-self.videoProperties.width/2, -self.videoProperties.height/2)
					ct.paint_with_alpha(alpha2)
			else:
				if scale1>0.01: #If scale is low, cairo can not scale the picture
					ct.translate(x1, y1)
					ct.scale(scale1, scale1)
					ct.rotate(angle1)
					ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),-self.videoProperties.width/2, -self.videoProperties.height/2)
					ct.paint_with_alpha(alpha2)
			if n==0:
				ct.restore()
		return imageSurface_get_pixbuf(im)


class TransitionSquaresFlying2(TransitionSquaresFlyingBase):
	def __init__(self, videoProperties, duration):
		TransitionSquaresFlyingBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionSquaresFlying2
		self.icon_path=install_path+'/icons/squaresflying2.svg'
	
	def coord_pixbuf1(self, t):
		x=self.videoProperties.width/2
		y=float(self.videoProperties.height/2.0)*(1.0-sin(t*pi+pi))
		scale=1.0-t*0.5
		z=scale
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		x=self.videoProperties.width/2
		y=float(self.videoProperties.height/2.0)*(1.0-sin(t*pi))
		scale=t*0.5+0.5
		z=scale
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha


class TransitionSquaresFlying3(TransitionSquaresFlyingBase):
	def __init__(self, videoProperties, duration):
		TransitionSquaresFlyingBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionSquaresFlying3
		self.icon_path=install_path+'/icons/squaresflying3.svg'
	
	def coord_pixbuf1(self, t):
		x=float(self.videoProperties.width/4.0)*(1.0-cos(2.0*t*pi+pi))
		y=float(self.videoProperties.height/4.0)*(2.0-sin(2.0*t*pi+pi))
		scale=1.0-t*0.5
		z=scale
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		x=float(self.videoProperties.width/4.0)*(3.0-cos(2.0*t*pi))
		y=float(self.videoProperties.height/4.0)*(2.0-sin(2.0*t*pi))
		scale=t*0.5+0.5
		z=scale
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha


class TransitionSquaresFlying4(TransitionSquaresFlyingBase):
	def __init__(self, videoProperties, duration):
		TransitionSquaresFlyingBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionSquaresFlying4
		self.icon_path=install_path+'/icons/squaresflying4.svg'
	
	def coord_pixbuf1(self, t):
		x=float(self.videoProperties.width/2.0)*(1.0-t)
		y=float(self.videoProperties.height/2.0)*(1.0-t)
		scale=1.0-t
		z=scale
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		x=float(self.videoProperties.width/2.0)*(2.0-t)
		y=float(self.videoProperties.height/2.0)*(2.0-t)
		scale=t
		z=scale
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha



class TransitionSquaresFlying5(TransitionSquaresFlyingBase):
	def __init__(self, videoProperties, duration):
		TransitionSquaresFlyingBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionSquaresFlying5
		self.icon_path=install_path+'/icons/squaresflying5.svg'
	
	def coord_pixbuf1(self, t):
		x=float(self.videoProperties.width/2.0)
		y=float(self.videoProperties.height/2.0)
		scale=1.0
		z=0.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		x=float(self.videoProperties.width/2.0)*(2.0-t)
		y=float(self.videoProperties.height/2.0)*(t)
		scale=t
		z=1.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha


class TransitionPushLeft(TransitionSquaresFlyingBase):
	def __init__(self, videoProperties, duration):
		TransitionSquaresFlyingBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionPushLeft
		self.icon_path=install_path+'/icons/pushleft.svg'
	
	def coord_pixbuf1(self, t):
		x=float(self.videoProperties.width/2.0)*(1.0-(sin(pi*t-pi/2.0)+1.0))
		y=float(self.videoProperties.height/2.0)
		scale=1.0
		z=0.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		x=float(self.videoProperties.width/2.0)*(3.0-(sin(pi*t-pi/2.0)+1.0))
		y=float(self.videoProperties.height/2.0)
		scale=1.0
		z=1.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha


class TransitionPushUp(TransitionSquaresFlyingBase):
	def __init__(self, videoProperties, duration):
		TransitionSquaresFlyingBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionPushUp
		self.icon_path=install_path+'/icons/pushup.svg'
	
	def coord_pixbuf1(self, t):
		y=float(self.videoProperties.height/2.0)*(1.0-(sin(pi*t-pi/2.0)+1.0))
		x=float(self.videoProperties.width/2.0)
		scale=1.0
		z=0.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha
	
	def coord_pixbuf2(self, t):
		y=float(self.videoProperties.height/2.0)*(3.0-(sin(pi*t-pi/2.0)+1.0))
		x=float(self.videoProperties.width/2.0)
		scale=1.0
		z=1.0
		angle=0.0
		alpha=1.0
		return x, y, z, scale, angle, alpha


class TransitionCircleClose(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		self.class_base=TransitionCircleClose
		self.icon_path=install_path+'/icons/circleclose.svg'
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint()
		radio=math.sqrt(self.videoProperties.width*self.videoProperties.width+self.videoProperties.height*self.videoProperties.height)
		alpha=radio*float(self.duration-t)/float(self.duration)
		if alpha>=radio:
			alpha=0.99*radio
		radial = cairo.RadialGradient(self.videoProperties.width*0.5, self.videoProperties.height*0.5, alpha, self.videoProperties.width*0.5, self.videoProperties.height*0.5, radio)
		radial.add_color_stop_rgba(0, 0, 0, 0, 1)
		radial.add_color_stop_rgba(0.05, 0, 0, 0, 0)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.mask(radial)
		return imageSurface_get_pixbuf(im)


class TransitionCircleOpen(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		self.class_base=TransitionCircleOpen
		self.icon_path=install_path+'/icons/circleopen.svg'
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint()
		radio=math.sqrt(self.videoProperties.width*self.videoProperties.width+self.videoProperties.height*self.videoProperties.height)
		if t<self.duration:
			alpha=radio*float(t)/float(self.duration)
		else:
			ct.paint()
			alpha=radio
		radial = cairo.RadialGradient(self.videoProperties.width*0.5, self.videoProperties.height*0.5, alpha, self.videoProperties.width*0.5, self.videoProperties.height*0.5, radio)
		radial.add_color_stop_rgba(0, 0, 0, 0, 1)
		radial.add_color_stop_rgba(0.05, 0, 0, 0, 0)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.mask(radial)
		return imageSurface_get_pixbuf(im)


class TransitionFigureBase(TransitionFade):
	def __init__(self, videoProperties, duration):
		TransitionFade.__init__(self, videoProperties, duration)
		self.class_base=TransitionFigureBase
		self.icon_path=install_path+'/icons/circleopen.svg'
	
	def mask_figure(self, t, ct):
		x=float(self.videoProperties.width)*0.5*(1.0-t)
		y=float(self.videoProperties.height)*0.5*(1.0-t)
		width=float(self.videoProperties.width)*t
		height=float(self.videoProperties.height)*t
		ct.rectangle(x,y,width, height)
		ct.fill()
	
	def render(self, t, pix1, pix2):
		im, ct=imageSurface_new(self.videoProperties.width, self.videoProperties.height)
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix1, self.videoProperties.width, self.videoProperties.height),0,0)
		ct.paint()
		ct.set_source_pixbuf(imageSurface_adjust_pixbuf_to_size( pix2, self.videoProperties.width, self.videoProperties.height),0,0)
		factor=float(t)/float(self.duration)
		self.mask_figure(factor, ct)
		return imageSurface_get_pixbuf(im)

class TransitionFigureHeart(TransitionFigureBase):
	def __init__(self, videoProperties, duration):
		TransitionFigureBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionFigureHeart
		self.icon_path=install_path+'/icons/heart.svg'
	
	def mask_figure(self, t, ct):
		#R=float(self.videoProperties.width)*0.5*t
		#r=R*0.5
		#alpha=pi-acos(2.0/3.0)
		#ALPHA=acos(1.0/6.0)
		#x=float(self.videoProperties.width)*0.5
		#y=float(self.videoProperties.height)*0.5-R/4.0-r*sqrt(5)/3.0
		#ct.move_to(x,y)
		#ct.arc(x+r*2.0/3.0, y+r*sqrt(5)/3.0, r, -alpha,0)
		#ct.arc(x-r/3.0, y+r*sqrt(5)/3.0, R, 0, ALPHA)
		#ct.arc(x+r/3.0, y+r*sqrt(5)/3.0, R, pi-ALPHA, pi)
		#ct.arc(x-r*2.0/3.0, y+r*sqrt(5)/3.0, r, pi-alpha+pi/2.0, 2.0*pi)
		R=float(self.videoProperties.width)*t
		r=R*0.5
		alpha=2.3005239830218627
		ALPHA=1.4033482475752073
		x=float(self.videoProperties.width)*0.5
		y=float(self.videoProperties.height)*0.5-R/4.0-r*0.7453559924999299
		ct.move_to(x,y)
		ct.arc(x+r*2.0/3.0, y+r*0.7453559924999299, r, -alpha,0)
		ct.arc(x-r/3.0, y+r*0.7453559924999299, R, 0, ALPHA)
		ct.arc(x+r/3.0, y+r*0.7453559924999299, R, pi-ALPHA, pi)
		ct.arc(x-r*2.0/3.0, y+r*0.7453559924999299, r, pi-alpha+pi/2.0, 2.0*pi)
		ct.fill()


class TransitionFigureStar5(TransitionFigureBase):
	def __init__(self, videoProperties, duration):
		TransitionFigureBase.__init__(self, videoProperties, duration)
		self.class_base=TransitionFigureStar5
		self.icon_path=install_path+'/icons/star5.svg'
		self.n=5.0
	
	def mask_figure(self, t, ct):
		r=float(self.videoProperties.width)*t
		R=r*2.0
		n=self.n
		alpha=2.0*pi*t
		x=float(self.videoProperties.width)*0.5+R*cos(alpha)
		y=float(self.videoProperties.height)*0.5+R*sin(alpha)
		ct.move_to(x,y)
		k=0
		while k<n:
			x=float(self.videoProperties.width)*0.5+R*cos(alpha)
			y=float(self.videoProperties.height)*0.5+R*sin(alpha)
			ct.line_to(x,y)
			alpha+=pi/n
			x=float(self.videoProperties.width)*0.5+r*cos(alpha)
			y=float(self.videoProperties.height)*0.5+r*sin(alpha)
			ct.line_to(x,y)
			alpha+=pi/n
			k+=1
		ct.fill()

class TransitionFigureStarMultiple(TransitionFigureStar5):
	def __init__(self, videoProperties, duration):
		TransitionFigureStar5.__init__(self, videoProperties, duration)
		self.class_base=TransitionFigureStarMultiple
		self.icon_path=install_path+'/icons/circleopen.svg'
		self.n=80.0
